using System;
using System.IO.Packaging;
using System.Xml;
using System.IO;
using System.Workflow.ComponentModel;
using System.ComponentModel;

namespace OWA.Activities
{
	public abstract class AbstractCustomXmlActivity
        : AbstractPackageActivity
    {
        protected static readonly string RT_CustomXml = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";
        protected static readonly string XMLNS_Datastore = "http://schemas.openxmlformats.org/officeDocument/2006/customXml";
        protected static readonly string RT_CustomXmlProperties = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps";
        
        public static DependencyProperty CustomXmlProperty = DependencyProperty.Register("CustomXml", typeof(XmlDocument), typeof(AbstractCustomXmlActivity));
        Guid _storeItemID;

        public Guid StoreItemID
        {
            get { return _storeItemID; }
            set { _storeItemID = value; }
        }

        [Description("The data to embed in the package.")]
        [Category("OWA")]
        [Browsable(true)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public XmlDocument CustomXml
        {
            get
            {
                return ((XmlDocument)(base.GetValue(EmbedCustomXmlActivity.CustomXmlProperty)));
            }
            set
            {
                base.SetValue(EmbedCustomXmlActivity.CustomXmlProperty, value);
            }
        }
        protected AbstractCustomXmlActivity()
        {
        }

        protected PackagePart GetCustomXmlPart(Package package, Guid storeItemID)
        {
            PackagePart mainPart = GetMainPart(package);
            PackagePart customXmlPart = null;
            foreach (PackageRelationship relationship in
                mainPart.GetRelationshipsByType(RT_CustomXml))
            {
                Uri customXmlUri = PackUriHelper.ResolvePartUri(
                    relationship.SourceUri, relationship.TargetUri);
                PackagePart possiblePart = package.GetPart(customXmlUri);
                if (HasStoreItemID(possiblePart, storeItemID))
                {
                    customXmlPart = possiblePart;
                    break;
                }
            }
            return customXmlPart;
        }

        private bool HasStoreItemID(PackagePart customXmlPart, Guid storeItemID)
        {
            bool hasStoreItemID = false;
            PackagePart propertiesPart = null;
            foreach (PackageRelationship relationship in
                customXmlPart.GetRelationshipsByType(RT_CustomXmlProperties))
            {
                Uri propertiesPartUri = PackUriHelper.ResolvePartUri(
                    relationship.SourceUri, relationship.TargetUri);
                propertiesPart = customXmlPart.Package.GetPart(propertiesPartUri);
                break;
            }
            if (propertiesPart != null)
            {
                try
                {
                    XmlDocument document = new XmlDocument();
                    using (Stream stream = propertiesPart.GetStream(
                        FileMode.Open, FileAccess.Read))
                    {
                        document.Load(stream);
                    }
                    XmlAttribute attribute = document.DocumentElement.Attributes["itemID", XMLNS_Datastore];
                    Guid id = new Guid(attribute.Value);
                    hasStoreItemID = id == storeItemID;
                }
                catch (XmlException)
                {
                    // defaulting to returning false, 
                    // if the package contains invalid XML, it 
                    // is not our business
                    // TODO: Raise warning
                }
            }
            return hasStoreItemID;
        }        

	}
}
